package com.dtp.core.handler;

import com.dtp.common.em.NotifyItemEnum;
import com.dtp.common.entity.NotifyItem;
import com.dtp.common.entity.TpMainFields;
import com.dtp.core.context.DtpNotifyCtxHolder;
import com.dtp.core.notify.DtpDingNotifier;
import com.dtp.core.notify.DtpLarkNotifier;
import com.dtp.core.notify.DtpNotifier;
import com.dtp.core.notify.DtpWechatNotifier;
import com.dtp.core.notify.base.DingNotifier;
import com.dtp.core.notify.base.LarkNotifier;
import com.dtp.core.notify.base.WechatNotifier;
import com.dtp.core.notify.manager.NotifyHelper;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;

/**
 * 通知者处理器
 *
 * @author yanhom
 * @since 1.0.0
 *
 * @remark muse
 **/
@Slf4j
public final class NotifierHandler {

    private static final Map<String, DtpNotifier> NOTIFIERS = new HashMap<>(); // 维护DtpNotifier实现类的缓存

    private NotifierHandler() {
        /**
         * 通过SPI的方式加载DtpNotifier的实现类集合
         *
         *【使用方法】
         * 此处可以在resources/META-INF/services/com.dtp.core.notify.DtpNotifier文件内添加自定义的DtpNotifier实现类的
         * 全路径名，那么该用户自定义类的实例对象就可以通过ServiceLoader.load加载进来了
         */
        // 步骤1：试图加载用户自定义的DtpNotifier实现类集合
        ServiceLoader<DtpNotifier> loader = ServiceLoader.load(DtpNotifier.class);
        for (DtpNotifier notifier : loader) NOTIFIERS.put(notifier.platform(), notifier);

        // 步骤2：将DtpDingNotifier、DtpWechatNotifier和DtpLarkNotifier维护到NOTIFIERS缓存中
        DtpNotifier dingNotifier = new DtpDingNotifier(new DingNotifier());
        DtpNotifier wechatNotifier = new DtpWechatNotifier(new WechatNotifier());
        DtpNotifier larkNotifier = new DtpLarkNotifier(new LarkNotifier());
        NOTIFIERS.put(dingNotifier.platform(), dingNotifier);
        NOTIFIERS.put(wechatNotifier.platform(), wechatNotifier);
        NOTIFIERS.put(larkNotifier.platform(), larkNotifier);
    }

    /** 遍历配置的消息发送平台，执行通知发送 */
    public void sendNotice(TpMainFields oldFields, List<String> diffs) {
        NotifyItem notifyItem = DtpNotifyCtxHolder.get().getNotifyItem();
        for (String platformId : notifyItem.getPlatformIds()) {
            NotifyHelper.getPlatform(platformId).ifPresent(p -> {
                DtpNotifier notifier = NOTIFIERS.get(p.getPlatform().toLowerCase());
                if (notifier != null) notifier.sendChangeMsg(p, oldFields, diffs);
            });
        }
    }

    /** 遍历配置的消息发送平台，执行警报发送 */
    public void sendAlarm(NotifyItemEnum notifyItemEnum) {
        NotifyItem notifyItem = DtpNotifyCtxHolder.get().getNotifyItem();
        for (String platformId : notifyItem.getPlatformIds()) {
            NotifyHelper.getPlatform(platformId).ifPresent(p -> {
                DtpNotifier notifier = NOTIFIERS.get(p.getPlatform().toLowerCase());
                if (notifier != null) notifier.sendAlarmMsg(p, notifyItemEnum);
            });
        }
    }

    /** 获得NotifierHandler单例实例对象 */
    public static NotifierHandler getInstance() {
        return NotifierHandlerHolder.INSTANCE;
    }
    private static class NotifierHandlerHolder {
        private static final NotifierHandler INSTANCE = new NotifierHandler();
    }
}
